package com.ly.mp.busicen.rule.flow;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import com.ly.mp.busicen.rule.config.XruleConfig;
import com.ly.mp.busicen.rule.flow.action.Action;
import com.ly.mp.busicen.rule.flow.action.IAction;

public class ActionContainer implements IActionContainer {
	
	@Autowired
	XruleConfig xruleConfig;
	
	Logger log = LoggerFactory.getLogger(ActionContainer.class);

	private List<Fragment> fragments = new ArrayList<Fragment>();
	
	private List<Fragment> fragmentsCust = new ArrayList<Fragment>();	
	
	public List<Fragment> getFragmentsCust() {
		return fragmentsCust;
	}

	public void setFragmentsCust(List<Fragment> fragmentsCust) {
		this.fragmentsCust = fragmentsCust;
	}

	private Map<String,List<IAction>> actionsCache = new ConcurrentHashMap<>();	

	public List<Fragment> getFragments() {
		return fragments;
	}

	public void setFragments(List<Fragment> fragments) {
		this.fragments = fragments;
	}

	// 入口类, 跟你你传递的flow ,会找数据库配置的所有脚本, 入口 com.ly.mp.busicen.rule.flow.FireFlow.fire(String, String, Map<String, Object>)
	// flow就是 BUSINESSFLOW_SENCECODE 字段
	@Override
	public List<IAction> flowActions(String flow, Map<String, Object> ctx) {
		if (StringUtils.isEmpty(ctx.get("oemCode"))||StringUtils.isEmpty(ctx.get("brandCode"))) {
			throw new FlowException("获取规则时对应对应厂商或品牌编码为空，无法找到配置");
		}
		String oemCode = String.valueOf(ctx.get("oemCode"));
		String brandCode = String.valueOf(ctx.get("brandCode"));
//		String cacheKey = flow+"^"+oemCode+"^"+brandCode;
		List<IAction> actions=null;//=actionsCache.get(cacheKey);
//		if(actions!=null) {
//			return RuleReLoad.cloneObj(actions);
//		}
		if(xruleConfig.xruleExtendCfg().currentCustMode()) {
			actions = fragmentsCust.stream()
					.filter(m -> flow.equals(m.getFlow())
							&& brandCode.equals(m.getBrand())
							&& oemCode.equals(m.getOem()))
					.map(m -> {
						IAction action = new Action();
						BeanUtils.copyProperties(m, action);
						action.extention().put(IAction.EXTKEY_BRAND, brandCode);
						return action;
					}).collect(Collectors.toList());
		}
		if(actions==null||actions.isEmpty()) {
			actions = fragments.stream()
					.filter(m -> flow.equals(m.getFlow())
							&& brandCode.equals(m.getBrand())
							&& oemCode.equals(m.getOem()))
					.map(m -> {
						IAction action = new Action();
						BeanUtils.copyProperties(m, action);
						action.extention().put(IAction.EXTKEY_BRAND, brandCode);
						return action;
					}).collect(Collectors.toList());
		}else {
			log.info("流程【{}】规则引擎流程使用客制化配置",flow);
		}
//		actionsCache.put(cacheKey, actions);
		return actions;// RuleReLoad.cloneObj(actions);
	}

	@Override
	public IAction action(String ruleCode) {
		if(xruleConfig.xruleExtendCfg().currentCustMode()) {
			Optional<Fragment> opt = fragmentsCust.stream().filter(f->ruleCode.equals(f.getRuleCode())).findFirst();
			if (opt.isPresent()) {
				log.info("规则【{}】规则引擎规则使用客制化配置",ruleCode);
				IAction action = new Action();
				BeanUtils.copyProperties(opt.get(), action);
				return action;
			}
		}
		Optional<Fragment> optx = fragments.stream().filter(f->ruleCode.equals(f.getRuleCode())).findFirst();
		if (optx.isPresent()) {
			IAction action = new Action();
			BeanUtils.copyProperties(optx.get(), action);
			return action;
		}
		
		return null;
	}

	@Override
	public void cleanCache() {
		actionsCache.clear();
	}
	

}
